import time
import json
import re
import datetime

import requests
from django.db.models import Count
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse
from django_redis import get_redis_connection

from info.models import Student, Class
from .models import ActLog, Activity, NoLog
from django.core.cache import cache  # 引入缓存模块
from urllib.parse import quote, unquote
from .utils import send_msg, query_all_dict, query_one_dict, get_checkCount


# Create your views here.

def get_msg(request):
    """
    机器人获取消息接口

     * @param int type                 =>   事件类型（事件列表可参考 - 事件列表demo）
     * @param int msg_type             =>   消息类型（仅在私聊和群消息事件中，代表消息的表现形式，如文字消息、语音、等等）
     * @param string from_wxid         =>   1级来源id（比如发消息的人的id）
     * @param string from_name         =>   1级来源昵称（比如发消息的人昵称）
     * @param string final_from_wxid   =>   2级来源id（群消息事件下，1级来源为群id，2级来源为发消息的成员id，私聊事件下都一样）
     * @param string final_nickname    =>   2级来源昵称
     * @param string robot_wxid        =>   当前登录的账号（机器人）标识id
     * @param string file_url          =>   如果是文件消息（图片、语音、视频、动态表情），这里则是可直接访问的网络地址，非文件消息时为空
     * @param string msg               =>   消息内容
     * @param string parameters        =>   附加参数（暂未用到，请忽略）
     * @param int time                 =>   请求时间(时间戳10位版本)


    :param request:
    :return:
    """

    def query2json(call: str):
        """
        将机器人回调的form表单转json

        :param call:
        :return:
        """
        return json.loads('{\"' + re.sub('(?<!&)&(?!&)', '\",\"', re.sub('(?<!=)=(?!=|&)', '\":\"', call)) + '\"}')

    if request.method == 'POST':
        # cache.set('data', request.body.decode("utf-8"))
        data = query2json(request.body.decode("utf-8"))

        if data['type'] in ['100', '200']:
            msg = unquote(data['msg'], 'utf-8')

            if "绑定" in msg:
                card = msg.replace('绑定', '').replace(' ', '')
                try:
                    stu = Student.objects.get(stu_card=card)
                    stu.wx_id = data['from_wxid']
                    stu.save()
                    msg = f'绑定成功：【{stu.cla.classname}】{stu.name}'
                except:
                    msg = '绑定出错，请检查学号'
                return send_msg(
                    # msg_type=data['type'],
                    msg_type=102,
                    msg=msg,
                    to_wxid=data['from_wxid'],
                    at_wxid=data['final_from_wxid'],
                    at_name=data['from_name']
                )

            elif "查" in msg:
                cla = msg.replace('查', '').replace(' ', '')

                try:
                    nolog = NoLog.objects.filter(classname__contains=cla)
                    msg = f'截止到当前时间{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))}\n' + cla + '未完成名单：\n'
                    for i in nolog:
                        msg += i.name + ', '
                except:
                    msg = '查询出错'
                return send_msg(
                    # msg_type=data['type'],
                    msg_type=102,
                    msg=msg,
                    to_wxid=data['from_wxid'],
                    at_wxid=data['final_from_wxid'],
                    at_name=data['from_name']
                )
            elif '汇报' in msg:
                msg = f'截止到当前时间{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))}\n\n'

                nolog = NoLog.objects.values("classname").annotate(c=Count("id"))
                # 之筛选出体院信息
                count = Student.objects.filter(status=0, cla__ins_id=1).values("cla__classname").annotate(c=Count("id"))
                index = 0

                for i in count:
                    total_person = i['c']
                    no_do = 0
                    for n in nolog:
                        if n['classname'] == i['cla__classname']:
                            no_do = n['c']

                    msg += f'{i["cla__classname"]}在校学生应检{total_person}人, 实检{total_person - no_do}人\n=============\n'
                    index += 1
                return send_msg(
                    # msg_type=data['type'],
                    msg_type=102,
                    msg=msg,
                    to_wxid=data['from_wxid'],
                    at_wxid=data['final_from_wxid'],
                    at_name=data['from_name']
                )

    JsonResponse({}, safe=False)


def check_count(request):
    """
    获取累计做核酸的次数

    :param request:
    :return:
    """
    return JsonResponse(
        {
            'code': 1,
            'data': get_checkCount(request.GET.get('stu_card')),
            'msg': '操作成功'
        },
        safe=False)


def checkLog(request):
    """
    签到

    :param request:
    :return:
    """
    stu_card = request.GET.get('stu_card')
    aid = request.GET.get('aid')
    data = {}

    if cache.has_key(f'user:{stu_card}'):
        data = cache.get(f'user:{stu_card}')
    else:
        try:
            stu = Student.objects.get(stu_card=stu_card)
            data = {
                'id': stu.id,
                'classname': stu.cla.classname,
                'name': stu.name,
            }
            cache.set(f'user:{stu_card}', data, timeout=None)
        except:
            return JsonResponse(
                {
                    'code': 0,
                    'data': None,
                    'msg': '学号错误或缺失'
                },
                safe=False)

    img_url = request.GET.get('url')
    print(aid, data, img_url)
    ActLog.objects.create(activity_id=aid, student_id=data['id'], img_url=img_url)

    data['count'] = get_checkCount(stu_card, True)  # 累计打卡次数+1

    return JsonResponse(
        {
            'code': 1,
            'data': data,
            'msg': '操作成功'
        },
        safe=False)


def act_list(requst):
    """
    获取活动列表

    :param requst:
    :return:
    """
    # datas = Activity.objects.all().order_by('-create_time')

    data = []

    if cache.has_key('acts'):  # 查找是否有缓存
        data = cache.get('acts')
        if len(data) > 0:  # 如果缓存数据为空
            return JsonResponse(data, safe=False)

    datas = Activity.objects.filter(status=1).order_by('-create_time')
    data = [{
        'id': i.id,
        'name': i.name
    } for i in datas]

    if len(data) > 0:
        cache.set('acts', data, 60 * 5)

    return JsonResponse(data, safe=False)


def like(request):
    """
    点赞和获取点赞信息

    :param request:
    :return:
    """
    likes = 0
    if not cache.has_key('like'):
        cache.set('like', 0, None)

    if request.method == 'GET':
        likes = cache.get('like')

    elif request.method == 'POST':
        likes = cache.incr('like', 1)

    return JsonResponse({'like': likes}, safe=False)


def get_count(request):
    """
    获取每次核酸打卡的人数变化（累计打卡次数柱状图）

    :return:
    """
    # query = query_all_dict("SELECT activity_id, sum(`count(*)`) AS count FROM `statistics` GROUP BY activity_id")
    query = query_all_dict(
        "SELECT activativies_activity.`name`, sum( `count(*)` ) AS count FROM `statistics` ,activativies_activity\n"
        "WHERE\n"
        "	activativies_activity.id=statistics.activity_id\n"
        "GROUP BY\n"
        "	activativies_activity.`name`\n"
        "    ")

    data = [
        {
            'name': i['name'],
            'count': round(i['count'])
        }
        for i in query
    ]
    return JsonResponse(data, safe=False)


def get_class_count(request):
    """
    获取各班级累计打卡次数（玫瑰饼图）

    :param request:
    :return:
    """
    query = query_all_dict("\n"
                           "    SELECT\n"
                           "	classname,\n"
                           "	SUM( `count(*)` ) AS count \n"
                           "FROM\n"
                           "	statistics \n"
                           "GROUP BY\n"
                           "	classname \n"
                           "ORDER BY\n"
                           "	count DESC\n"
                           "LIMIT 9\n"
                           "	")
    total = query_one_dict("SELECT count(*) AS total FROM statistics")['total']
    data = [
        {
            'name': i['classname'],
            'value': round(i['count'])
        }
        for i in query
    ]
    data.append({'name': '其他', 'value': round(total)})
    return JsonResponse(data, safe=False)


def close_comment(func):
    def close(*args, **kwargs):
        if args[0].method == 'POST':
            return JsonResponse({'code': 0, 'msg': '评论功能已经关闭'}, safe=False)
        else:
            return func(*args, **kwargs)
    return close


# @close_comment
def comment(request):
    """
    评论和获取评论

    :param request:
    :return:
    """

    conn = get_redis_connection('default')

    conn.rpush('key_name', str({"api_key": "1234"}))

    if request.method == "GET":
        # 查询评论
        try:
            page = int(request.GET.get('page'))
        except:
            page = 1
        if not page:
            page = 1
        data = []
        for i in conn.lrange('comment', (page - 1) * 10, page * 10):
            i = json.loads(str(i, 'utf-8'))
            data.append({
                'classname': i['classname'],
                'name': i['name'],
                'text': i['text'],
                'time': i['time']
            })
        return JsonResponse(data, safe=False)

    if request.method == "POST":
        try:
            classname = request.POST.get('classname')
            name = request.POST.get('name')
            text = request.POST.get('text')

            conn.lpush('comment', json.dumps({
                'classname': classname,
                'name': name,
                'text': text,
                'time': str(datetime.datetime.now())
            }))

            return JsonResponse({'code': 1, 'msg': '发表成功！'}, safe=False)
        except:
            return JsonResponse({'code': 0, 'msg': '发表失败！'}, safe=False)
